package org.melanesia.sql;

import org.melanesia.converters.JavaToJavaConverter;

/**
 * A factory class for injecting into the framework in order to manage
 * instantiation of beans when mapping records from SQL query. This class can be
 * used to instantiate different subclasses of the main class (passed for
 * example to {@link org.melanesia.sql.Query#execute(Class)}) using the
 * discriminator value (a value from column of the sql result set) do
 * distinguish types of created objects.
 *
 * @author marcin.kielar
 */
public abstract class BeanClassFactory {

	/**
	 * Returns bean class for specified discriminator value.
	 * @param discriminatorValue discriminator value obtained from result set
	 * @return class to instantiate
	 */
	public abstract Class<?> getBeanClass(Object discriminatorValue);

	/**
	 * Returns the name of the column or output parameter to be used as a type discriminator for this factory.
	 * @return discriminator name
	 */
	public abstract String getDiscriminator();

	/**
	 * Determines if specified result (column or output parameter) should be ignored for specific discriminator.
	 * Subclasses can override this method in order to ignore sets of SQL results depending on discriminator value.
	 *
	 * @param resultName	name of the column or output parameter
	 * @param discriminatorValue discriminator value obtained from result set
	 *
	 * @return true if the result should be ignored
	 */
	public final boolean isResultIgnored(final String resultName, final Object discriminatorValue) {
		return false;
	}

	    /**
     * Returns explicit converter for a result (column or output parameter)
     * depending on discriminator. Subclasses may override this method in order
     * to specify different converters depending on the discriminator value.
     *
     * This can be used to differentiate conversion methods in a situations,
     * where the result is mapped to different java types depending on the class
     * returned by {@link #getBeanClass(Object)}.
     *
     * For example, we have these two classes returned by
     * {@link #getBeanClass(Object)}:
     *
     * <pre>
     * {
     *     &#064;code
     *     public class A {
     *         public String field;
     *     }
     *
     *     public class B {
     *         public Integer[] field;
     *     }
     *
     * }
     * </pre>
     *
     * Now, the SQL looks something like {@code SELECT ... AS FIELD FROM ....}.
     * That means, that the FIELD column (being a VARCHAR) should be mapped to a
     * String or to an array of integers depending on the class used.
     *
     * In this case, one can use {@link #getResultConverter(String, Object)} to
     * return converters specific for a type associated with discriminator value
     *
     * @param resultName name of the sql column or output parameter
     * @param discriminatorValue discriminator value
     * @return result converter
     */
	public final JavaToJavaConverter getResultConverter(final String resultName, final Object discriminatorValue) {
		return null;
	}
}
